﻿#include "HttpService.h"
#include "../MessageQueue.h"
#include "../Settings.h"

namespace Server::Library::Utils
{

    HttpService::HttpService()
    {
    }

    void HttpService::Listen()
    {
        if (!HttpListener::IsSupported)
        {
            throw InvalidOperationException("To use HttpListener the operating system must be Windows XP SP2 or Server 2003 or higher.");
        }
        std::vector<std::string> prefixes = {Host};

        _listener = new HttpListener();
        try
        {
            for (auto s : prefixes)
            {
                _listener->Prefixes->Add(s);
            }
            _listener->Start();
            MessageQueue::getInstance()->Enqueue("HttpService started.");
        }
        catch (const std::runtime_error &err)
        {
            MessageQueue::getInstance()->Enqueue("HttpService start failed! Error:" + err);
            return;
        }


        while (_isActive)
        {
            try
            {
                auto context = _listener->GetContext();
                auto request = context->Request;
                std::cout << request->HttpMethod << " " << request->RawUrl << std::endl;
                std::cout << "User-Agent: " << request->UserAgent << std::endl;
                std::cout << "Accept-Encoding: " << request->Headers["Accept-Encoding"] << std::endl;
                std::cout << "Connection: " << request->KeepAlive ? "Keep-Alive" : "close" << std::endl;
                std::cout << "Host: " << request->UserHostName << std::endl;
                auto response = context->Response;
                if (context->Request->RemoteEndPoint != nullptr)
                {
//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to 'ToString':
                    auto clientIp = context->Request->RemoteEndPoint->Address->ToString();

                    if (clientIp != Settings::HTTPTrustedIPAddress)
                    {
                        WriteResponse(response, "notrusted:" + clientIp);
                        continue;
                    }
                }

                if (request->HttpMethod == "GET")
                {
                    OnGetRequest(request, response);
                }
                else
                {
                    OnPostRequest(request, response);
                }
            }
            catch (...)
            {
            }
        }
    }

    void HttpService::Stop()
    {
        _isActive = false;
        if (_listener != nullptr && _listener->IsListening)
        {
            _listener->Stop();
        }
    }

    void HttpService::WriteResponse(HttpListenerResponse *response, const std::string &responseString)
    {
        try
        {
            response->ContentLength64 = Encoding::UTF8->GetByteCount(responseString);
            response->ContentType = "text/html; charset=UTF-8";
        }
//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to the exception 'finally' clause:
        finally
        {
            auto output = response->OutputStream;
            auto writer = new StreamWriter(output);
            writer->Write(responseString);
            writer->Close();

            delete writer;
        }
    }
}
